﻿using socket_client;
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

public static class GlobalScheduler
{
    // ========== 成员变量 ==========
    private static readonly ConcurrentDictionary<string, ScheduledTask> _dailyTasks =
        new ConcurrentDictionary<string, ScheduledTask>();
    private static readonly ConcurrentDictionary<string, IntervalTask> _intervalTasks =
        new ConcurrentDictionary<string, IntervalTask>();
    private static Timer _timer;
    private static readonly object _timerLock = new object();
    private static bool _isDisposed;

    // ========== 公开方法 ==========

    /// <summary>
    /// 添加每日定时任务
    /// </summary>
    public static void AddDailyTask(
        string taskId,
        Action action,
        TimeSpan targetTime,
        bool runImmediatelyIfMissed = true)
    {
        if (_isDisposed) throw new ObjectDisposedException(nameof(GlobalScheduler));

        lock (_timerLock)
        {
            _dailyTasks[taskId] = new ScheduledTask
            {
                Action = action,
                TargetTime = targetTime,
                RunImmediatelyIfMissed = runImmediatelyIfMissed,
                LastRunTime = null
            };

            EnsureTimerInitialized();
        }
    }

    /// <summary>
    /// 添加间隔任务（每隔指定分钟执行）
    /// </summary>
    public static void AddIntervalTask(
        string taskId,
        Action action,
        int intervalMinutes,
        bool runImmediately = true)
    {
        AsyncFileLogger.WriteLog("添加间隔任务");
        if (_isDisposed) throw new ObjectDisposedException(nameof(GlobalScheduler));
        if (intervalMinutes <= 0) throw new ArgumentException("间隔时间必须大于0分钟");

        lock (_timerLock)
        {
            _intervalTasks[taskId] = new IntervalTask
            {
                Action = action,
                Interval = TimeSpan.FromMinutes(intervalMinutes),
                NextRunTime = runImmediately ? DateTime.Now : DateTime.Now.AddMinutes(intervalMinutes)
            };

            EnsureTimerInitialized();
        }
    }

    /// <summary>
    /// 移除任务
    /// </summary>
    public static bool RemoveTask(string taskId)
    {
        lock (_timerLock)
        {
            bool removedDaily = _dailyTasks.TryRemove(taskId, out _);
            bool removedInterval = _intervalTasks.TryRemove(taskId, out _);
            return removedDaily || removedInterval;
        }
    }

    /// <summary>
    /// 释放所有资源
    /// </summary>
    public static void Dispose()
    {
        lock (_timerLock)
        {
            if (_isDisposed) return;
            _isDisposed = true;
            _timer?.Dispose();
            _dailyTasks.Clear();
            _intervalTasks.Clear();
        }
    }

    // ========== 核心逻辑 ==========
    private static void EnsureTimerInitialized()
    {
        if (_timer == null)
        {
            _timer = new Timer(
                callback: CheckTasks,
                state: null,
                dueTime: 0,
                period: 1000 // 10s检查一次
            );
        }
    }

    private static void CheckTasks(object state)
    {
        if (_isDisposed) return;

        try
        {
            // 处理每日任务
            foreach (var taskEntry in _dailyTasks)
            {
                var taskId = taskEntry.Key;
                var task = taskEntry.Value;

                DateTime now = DateTime.Now;
                DateTime targetToday = now.Date.Add(task.TargetTime);

                bool shouldRun = task.RunImmediatelyIfMissed
                    ? (now >= targetToday && (task.LastRunTime == null || task.LastRunTime.Value.Date < now.Date))
                    : (now >= targetToday && (task.LastRunTime == null || task.LastRunTime < targetToday));

                if (shouldRun)
                {
                    Task.Run(() => ExecutDailyTask(taskId, task));
                }
            }

            // 处理间隔任务
            foreach (var taskEntry in _intervalTasks)
            {
                var taskId = taskEntry.Key;
                var task = taskEntry.Value;

                if (DateTime.Now >= task.NextRunTime)
                {
                    Task.Run(() => ExecuteIntervalTask(taskId, task));
                    // 更新下一次执行时间
                    task.NextRunTime = DateTime.Now.Add(task.Interval);
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"任务检查异常: {ex}");
        }
    }

    // ========== 任务执行 ==========
    private static void ExecutDailyTask(string taskId, ScheduledTask task)
    {
        try
        {
            task.Action();
            task.LastRunTime = DateTime.Now;
            Console.WriteLine($"[每日任务 {taskId}] 执行成功");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"[每日任务 {taskId}] 执行失败: {ex}");
        }
    }

    private static void ExecuteIntervalTask(string taskId, IntervalTask task)
    {
        try
        {
            task.Action();
            Console.WriteLine($"[间隔任务 {taskId}] 执行成功");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"[间隔任务 {taskId}] 执行失败: {ex}");
        }
    }

    // ========== 内部类 ==========
    private class ScheduledTask
    {
        public Action Action { get; set; }
        public TimeSpan TargetTime { get; set; }
        public bool RunImmediatelyIfMissed { get; set; }
        public DateTime? LastRunTime { get; set; }
    }

    private class IntervalTask
    {
        public Action Action { get; set; }
        public TimeSpan Interval { get; set; }
        public DateTime NextRunTime { get; set; }
    }
}